﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MugenInjection.Core;
using MugenInjection.Infrastructure;
using MugenInjection.Interface;
using MugenInjection.Interface.Components;
using MugenInjection.Syntax;
using MugenInjection.Syntax.Type;

namespace MugenInjection
{
    /// <summary>
    /// Represents the extension method for <see cref="IInjector"/>.
    /// </summary>
    public static class InjectorExtension
    {
        #region Get

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        public static object Get(this IInjectorResolver injector, Type service, object key,
                                 IDictionary<string, object> specialParameters = null,
                                 params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.Get(injector, service, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        public static object Get(this IInjectorResolver injector, Type service,
                                 IDictionary<string, object> specialParameters, params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.Get(injector, service, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        public static object Get(this IInjectorResolver injector, Type service, params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.Get(injector, service, null, null,
                                              InjectorUtilsInternal.ReadOnlyEmptyDictionary, parameters);
        }

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="key">The specified binding key.</param>
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        public static object GetInto(this IInjectorResolver injector, Type service, object key, MemberInfo member,
                                     ParameterInfo parameter = null,
                                     IDictionary<string, object> specialParameters = null,
                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.Get(injector, service, member, parameter, specialParameters, parameters);
        }

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        public static object GetInto(this IInjectorResolver injector, Type service, MemberInfo member,
                                     ParameterInfo parameter = null,
                                     IDictionary<string, object> specialParameters = null,
                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.Get(injector, service, member, parameter, specialParameters, parameters);
        }

        //------------

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <param name="key">The specified binding key.</param>
        /// <returns>An instance of the service.</returns>
        public static T Get<T>(this IInjectorResolver injector, object key,
                               IDictionary<string, object> specialParameters = null,
                               params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return (T)InjectorExtensionUtils.Get(injector, typeof(T), null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        public static T Get<T>(this IInjectorResolver injector, IDictionary<string, object> specialParameters,
                               params IInjectionParameter[] parameters)
        {
            return (T)InjectorExtensionUtils.Get(injector, typeof(T), null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        public static T Get<T>(this IInjectorResolver injector, params IInjectionParameter[] parameters)
        {
            return
                (T)
                InjectorExtensionUtils.Get(injector, typeof(T), null, null,
                                           InjectorUtilsInternal.ReadOnlyEmptyDictionary, parameters);
        }

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="key">The specified binding key.</param>
        /// <returns>An instance of the service.</returns>
        public static T GetInto<T>(this IInjectorResolver injector, object key, MemberInfo member,
                                   ParameterInfo parameter = null, IDictionary<string, object> specialParameters = null,
                                   params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return
                (T)InjectorExtensionUtils.Get(injector, typeof(T), member, parameter, specialParameters, parameters);
        }

        /// <summary>
        /// Gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <returns>An instance of the service.</returns>
        public static T GetInto<T>(this IInjectorResolver injector, MemberInfo member, ParameterInfo parameter = null,
                                   IDictionary<string, object> specialParameters = null,
                                   params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return
                (T)InjectorExtensionUtils.Get(injector, typeof(T), member, parameter, specialParameters, parameters);
        }

        #endregion

        #region Try get

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">An instance of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding name.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGet(this IInjectorResolver injector, Type service, out object result, object key,
                                  IDictionary<string, object> specialParameters = null,
                                  params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGet(injector, out result, service, null, null, specialParameters,
                                                 parameters);
        }

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">An instance of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGet(this IInjectorResolver injector, Type service, out object result,
                                  IDictionary<string, object> specialParameters, params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGet(injector, out result, service, null, null, specialParameters,
                                                 parameters);
        }

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">An instance of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGet(this IInjectorResolver injector, Type service, out object result,
                                  params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGet(injector, out result, service, null, null,
                                                 InjectorUtilsInternal.ReadOnlyEmptyDictionary, parameters);
        }

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">An instance of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="member"><see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="key">The specified binding key. </param>
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetInto(this IInjectorResolver injector, Type service, out object result, string key,
                                      MemberInfo member, ParameterInfo parameter = null,
                                      IDictionary<string, object> specialParameters = null,
                                      params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGet(injector, out result, service, member, parameter, specialParameters,
                                                 parameters);
        }

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">An instance of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetInto(this IInjectorResolver injector, Type service, out object result,
                                      MemberInfo member, ParameterInfo parameter = null,
                                      IDictionary<string, object> specialParameters = null,
                                      params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.TryGet(injector, out result, service, member, parameter, specialParameters,
                                                 parameters);
        }

        //------------

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <param name="result">An instance of the service.</param>
        /// <param name="key">The specified binding key. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGet<T>(this IInjectorResolver injector, out T result, object key,
                                     IDictionary<string, object> specialParameters = null,
                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGet(injector, out result, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <param name="result">An instance of the service.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGet<T>(this IInjectorResolver injector, out T result,
                                     IDictionary<string, object> specialParameters,
                                     params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGet(injector, out result, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Tries get an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <param name="result">An instance of the service.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGet<T>(this IInjectorResolver injector, out T result,
                                     params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGet(injector, out result, null, null,
                                                 InjectorUtilsInternal.ReadOnlyEmptyDictionary, parameters);
        }

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <param name="result">An instance of the service.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="key">The specified binding key. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetInto<T>(this IInjectorResolver injector, out T result, object key, MemberInfo member,
                                         ParameterInfo parameter = null,
                                         IDictionary<string, object> specialParameters = null,
                                         params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGet(injector, out result, member, parameter, specialParameters, parameters);
        }

        /// <summary>
        /// Try gets an instance of the specified service.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <param name="result">An instance of the service.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetInto<T>(this IInjectorResolver injector, out T result, MemberInfo member,
                                         ParameterInfo parameter = null,
                                         IDictionary<string, object> specialParameters = null,
                                         params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.TryGet(injector, out result, member, parameter, specialParameters, parameters);
        }

        #endregion

        #region Get all in current

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAllInCurrent(this IInjectorResolver injector, Type service, object key,
                                                          IDictionary<string, object> specialParameters = null,
                                                          params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.GetAllInCurrent(injector, service, null, null, specialParameters, false,
                                                          parameters);
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAllInCurrent(this IInjectorResolver injector, Type service,
                                                          IDictionary<string, object> specialParameters,
                                                          params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.GetAllInCurrent(injector, service, null, null, specialParameters, false,
                                                          parameters);
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAllInCurrent(this IInjectorResolver injector, Type service,
                                                          params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.GetAllInCurrent(injector, service, null, null,
                                                          InjectorUtilsInternal.ReadOnlyEmptyDictionary, true,
                                                          parameters);
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAllInCurrentInto(this IInjectorResolver injector, Type service, object key,
                                                              MemberInfo member, ParameterInfo parameter = null,
                                                              IDictionary<string, object> specialParameters = null,
                                                              params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.GetAllInCurrent(injector, service, member, parameter, specialParameters, false,
                                                          parameters);
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAllInCurrentInto(this IInjectorResolver injector, Type service,
                                                              MemberInfo member, ParameterInfo parameter = null,
                                                              IDictionary<string, object> specialParameters = null,
                                                              params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.GetAllInCurrent(injector, service, member, parameter, specialParameters, false,
                                                          parameters);
        }

        //-----------

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAllInCurrent<T>(this IInjectorResolver injector, object key,
                                                        IDictionary<string, object> specialParameters = null,
                                                        params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils
                .GetAllInCurrent(injector, typeof(T), null, null, specialParameters, false, parameters)
                .Cast<T>();
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAllInCurrent<T>(this IInjectorResolver injector,
                                                        IDictionary<string, object> specialParameters,
                                                        params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils
                .GetAllInCurrent(injector, typeof(T), null, null, specialParameters, false, parameters)
                .Cast<T>();
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAllInCurrent<T>(this IInjectorResolver injector,
                                                        params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils
                .GetAllInCurrent(injector, typeof(T), null, null, InjectorUtilsInternal.ReadOnlyEmptyDictionary, true,
                                 parameters)
                .Cast<T>();
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAllInCurrentInto<T>(this IInjectorResolver injector, object key,
                                                            MemberInfo member, ParameterInfo parameter = null,
                                                            IDictionary<string, object> specialParameters = null,
                                                            params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils
                .GetAllInCurrent(injector, typeof(T), member, parameter, specialParameters, false, parameters)
                .Cast<T>();
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAllInCurrentInto<T>(this IInjectorResolver injector, MemberInfo member,
                                                            ParameterInfo parameter = null,
                                                            IDictionary<string, object> specialParameters = null,
                                                            params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils
                .GetAllInCurrent(injector, typeof(T), member, parameter, specialParameters, false, parameters)
                .Cast<T>();
        }

        #endregion

        #region Try get all in current

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrent(this IInjectorResolver injector, Type service,
                                              out IEnumerable<object> result,
                                              object key, IDictionary<string, object> specialParameters = null,
                                              params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, service, null, null,
                                                             specialParameters, false, parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrent(this IInjectorResolver injector, Type service,
                                              out IEnumerable<object> result,
                                              IDictionary<string, object> specialParameters,
                                              params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, service, null, null,
                                                             specialParameters, false, parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrent(this IInjectorResolver injector, Type service,
                                              out IEnumerable<object> result, params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, service, null, null,
                                                             InjectorUtilsInternal.ReadOnlyEmptyDictionary, true,
                                                             parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrentInto(this IInjectorResolver injector, Type service,
                                                  out IEnumerable<object> result,
                                                  object key, MemberInfo member, ParameterInfo parameter = null,
                                                  IDictionary<string, object> specialParameters = null,
                                                  params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, service, member, parameter,
                                                             specialParameters, false, parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrentInto(this IInjectorResolver injector, Type service,
                                                  out IEnumerable<object> result, MemberInfo member,
                                                  ParameterInfo parameter = null,
                                                  IDictionary<string, object> specialParameters = null,
                                                  params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, service, member, parameter,
                                                             specialParameters, false, parameters);
        }

        //-----

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrent<T>(this IInjectorResolver injector, out IEnumerable<T> result, object key,
                                                 IDictionary<string, object> specialParameters = null,
                                                 params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, null, null, specialParameters, false,
                                                             parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrent<T>(this IInjectorResolver injector, out IEnumerable<T> result,
                                                 IDictionary<string, object> specialParameters,
                                                 params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, null, null, specialParameters, false,
                                                             parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrent<T>(this IInjectorResolver injector, out IEnumerable<T> result,
                                                 params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, null, null,
                                                             InjectorUtilsInternal.ReadOnlyEmptyDictionary, true,
                                                             parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrentInto<T>(this IInjectorResolver injector, out IEnumerable<T> result,
                                                     object key, MemberInfo member, ParameterInfo parameter = null,
                                                     IDictionary<string, object> specialParameters = null,
                                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, member, parameter, specialParameters,
                                                             false,
                                                             parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjectorResolver"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInCurrentInto<T>(this IInjectorResolver injector, out IEnumerable<T> result,
                                                     MemberInfo member, ParameterInfo parameter = null,
                                                     IDictionary<string, object> specialParameters = null,
                                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.TryGetAllInCurrent(injector, out result, member, parameter, specialParameters,
                                                             false,
                                                             parameters);
        }

        #endregion

        #region Get all

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAll(this IInjectorResolver injector, Type service, object key,
                                                 IDictionary<string, object> specialParameters = null,
                                                 params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.GetAll(injector, service, null, null, specialParameters, false, parameters);
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAll(this IInjectorResolver injector, Type service,
                                                 IDictionary<string, object> specialParameters,
                                                 params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.GetAll(injector, service, null, null, specialParameters, false, parameters);
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAll(this IInjectorResolver injector, Type service,
                                                 params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.GetAll(injector, service, null, null,
                                                 InjectorUtilsInternal.ReadOnlyEmptyDictionary, true, parameters);
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAllInto(this IInjectorResolver injector, Type service, object key,
                                                     MemberInfo member, ParameterInfo parameter = null,
                                                     IDictionary<string, object> specialParameters = null,
                                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.GetAll(injector, service, member, parameter, specialParameters, false,
                                                 parameters);
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<object> GetAllInto(this IInjectorResolver injector, Type service, MemberInfo member,
                                                     ParameterInfo parameter = null,
                                                     IDictionary<string, object> specialParameters = null,
                                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.GetAll(injector, service, member, parameter, specialParameters, false,
                                                 parameters);
        }


        //-------------------

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAll<T>(this IInjectorResolver injector, object key,
                                               IDictionary<string, object> specialParameters = null,
                                               params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils
                .GetAll(injector, typeof(T), null, null, specialParameters, false, parameters)
                .Cast<T>();
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAll<T>(this IInjectorResolver injector, IDictionary<string, object> specialParameters,
                                               params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils
                .GetAll(injector, typeof(T), null, null, specialParameters, false, parameters)
                .Cast<T>();
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAll<T>(this IInjectorResolver injector, params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils
                .GetAll(injector, typeof(T), null, null, InjectorUtilsInternal.ReadOnlyEmptyDictionary, true,
                        parameters)
                .Cast<T>();
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAllInto<T>(this IInjectorResolver injector, object key, MemberInfo member,
                                                   ParameterInfo parameter = null,
                                                   IDictionary<string, object> specialParameters = null,
                                                   params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils
                .GetAll(injector, typeof(T), member, parameter, specialParameters, false, parameters)
                .Cast<T>();
        }

        /// <summary>
        /// Gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns>A series of instances of the service.</returns>
        public static IEnumerable<T> GetAllInto<T>(this IInjectorResolver injector, MemberInfo member,
                                                   ParameterInfo parameter = null,
                                                   IDictionary<string, object> specialParameters = null,
                                                   params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils
                .GetAll(injector, typeof(T), member, parameter, specialParameters, false, parameters)
                .Cast<T>();
        }

        #endregion

        #region Try get all

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAll(this IInjectorResolver injector, Type service, out IEnumerable<object> result, object key,
                                     IDictionary<string, object> specialParameters = null,
                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGetAll(injector, out result, service, null, null, specialParameters, false,
                                                    parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAll(this IInjectorResolver injector, Type service, out IEnumerable<object> result,
                                     IDictionary<string, object> specialParameters,
                                     params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGetAll(injector, out result, service, null, null, specialParameters, false,
                                                    parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAll(this IInjectorResolver injector, Type service, out IEnumerable<object> result,
                                     params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGetAll(injector, out result, service, null, null,
                                                    InjectorUtilsInternal.ReadOnlyEmptyDictionary, true, parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInto(this IInjectorResolver injector, Type service, out IEnumerable<object> result,
                                         object key, MemberInfo member, ParameterInfo parameter = null,
                                         IDictionary<string, object> specialParameters = null,
                                         params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGetAll(injector, out result, service, member, parameter, specialParameters,
                                                    false, parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="service">The specified service type.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInto(this IInjectorResolver injector, Type service, out IEnumerable<object> result,
                                         MemberInfo member, ParameterInfo parameter = null,
                                         IDictionary<string, object> specialParameters = null,
                                         params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.TryGetAll(injector, out result, service, member, parameter, specialParameters,
                                                    false, parameters);
        }

        //--------------

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAll<T>(this IInjectorResolver injector, out IEnumerable<T> result, object key,
                                        IDictionary<string, object> specialParameters = null,
                                        params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGetAll(injector, out result, null, null, specialParameters, false,
                                                    parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAll<T>(this IInjectorResolver injector, out IEnumerable<T> result,
                                        IDictionary<string, object> specialParameters,
                                        params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGetAll(injector, out result, null, null, specialParameters, false,
                                                    parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAll<T>(this IInjectorResolver injector, out IEnumerable<T> result,
                                        params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.TryGetAll(injector, out result, null, null,
                                                    InjectorUtilsInternal.ReadOnlyEmptyDictionary, true, parameters);
        }


        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInto<T>(this IInjectorResolver injector, out IEnumerable<T> result, object key,
                                            MemberInfo member, ParameterInfo parameter = null,
                                            IDictionary<string, object> specialParameters = null,
                                            params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.TryGetAll(injector, out result, member, parameter, specialParameters, false,
                                                    parameters);
        }

        /// <summary>
        /// Try gets all available instances of the specified service in the specified <see cref="IInjector"/> include all of its parent <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="result">A series of instances of the service.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool TryGetAllInto<T>(this IInjectorResolver injector, out IEnumerable<T> result, MemberInfo member,
                                            ParameterInfo parameter = null,
                                            IDictionary<string, object> specialParameters = null,
                                            params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.TryGetAll(injector, out result, member, parameter, specialParameters, false,
                                                    parameters);
        }

        #endregion

        #region Binding

        #region Bind

        /// <summary>
        /// Declares a binding for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="services">The specified service <see cref="Type"/>(s).</param>
        /// <returns>The fluent syntax.</returns>
        public static IBindingSyntax Bind(this IInjector injector, params Type[] services)
        {
            return InjectorExtensionUtils.Bind(injector, false, services);
        }

        /// <summary>
        /// Declares a binding for the specified service <see cref="T"/>.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T> Bind<T>(this IInjector injector)
        {
            return InjectorExtensionUtils.Bind<T>(injector, false);
        }

        /// <summary>
        /// Declares a binding for the specified services.
        /// </summary>
        /// <typeparam name="T1">The specified service type.</typeparam>
        /// <typeparam name="T2">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T1, T2> Bind<T1, T2>(this IInjector injector)
        {
            return InjectorExtensionUtils.Bind<T1, T2>(injector, false);
        }

        /// <summary>
        /// Declares a binding for the specified services.
        /// </summary>
        /// <typeparam name="T1">The specified service type.</typeparam>
        /// <typeparam name="T2">The specified service type.</typeparam>
        /// <typeparam name="T3">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T1, T2, T3> Bind<T1, T2, T3>(this IInjector injector)
        {
            return InjectorExtensionUtils.Bind<T1, T2, T3>(injector, false);
        }

        /// <summary>
        /// Declares a binding for the specified services.
        /// </summary>
        /// <typeparam name="T1">The specified service type.</typeparam>
        /// <typeparam name="T2">The specified service type.</typeparam>
        /// <typeparam name="T3">The specified service type.</typeparam>
        /// <typeparam name="T4">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T1, T2, T3, T4> Bind<T1, T2, T3, T4>(this IInjector injector)
        {
            return InjectorExtensionUtils.Bind<T1, T2, T3, T4>(injector, false);
        }


        /// <summary>
        /// Declares a binding for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="services">The specified service <see cref="Type"/>(s).</param>
        /// <returns>The fluent syntax.</returns>
        public static IBindingSyntax BindWithManualBuild(this IInjector injector, params Type[] services)
        {
            return InjectorExtensionUtils.Bind(injector, true, services);
        }

        /// <summary>
        /// Declares a binding for the specified service <see cref="T"/>.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T> BindWithManualBuild<T>(this IInjector injector)
        {
            return InjectorExtensionUtils.Bind<T>(injector, true);
        }

        /// <summary>
        /// Declares a binding for the specified services.
        /// </summary>
        /// <typeparam name="T1">The specified service type.</typeparam>
        /// <typeparam name="T2">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T1, T2> BindWithManualBuild<T1, T2>(this IInjector injector)
        {
            return InjectorExtensionUtils.Bind<T1, T2>(injector, true);
        }

        /// <summary>
        /// Declares a binding for the specified services.
        /// </summary>
        /// <typeparam name="T1">The specified service type.</typeparam>
        /// <typeparam name="T2">The specified service type.</typeparam>
        /// <typeparam name="T3">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T1, T2, T3> BindWithManualBuild<T1, T2, T3>(this IInjector injector)
        {
            return InjectorExtensionUtils.Bind<T1, T2, T3>(injector, true);
        }

        /// <summary>
        /// Declares a binding for the specified services.
        /// </summary>
        /// <typeparam name="T1">The specified service type.</typeparam>
        /// <typeparam name="T2">The specified service type.</typeparam>
        /// <typeparam name="T3">The specified service type.</typeparam>
        /// <typeparam name="T4">The specified service type.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T1, T2, T3, T4> BindWithManualBuild<T1, T2, T3, T4>(this IInjector injector)
        {
            return InjectorExtensionUtils.Bind<T1, T2, T3, T4>(injector, true);
        }

        /// <summary>
        /// Declares a binding for the specified service <see cref="T"/>.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <typeparam name="TTypeTo">Type to bind specified service. </typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static ITypeCallbackConstructorObjectPriorityScopeUseWhenWithSyntax<TTypeTo> BindTo<T, TTypeTo>(
            this IInjector injector) where TTypeTo : T
        {
            return InjectorExtensionUtils.BindTo<T, TTypeTo>(injector, false);
        }

        /// <summary>
        /// Declares a binding for the specified service <see cref="T"/>.
        /// </summary>
        /// <typeparam name="T">The specified service type.</typeparam>
        /// <typeparam name="TTypeTo">Type to bind specified service. </typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <returns>The fluent syntax.</returns>
        public static ITypeCallbackConstructorObjectPriorityScopeUseWhenWithSyntax<TTypeTo> BindToWithManualBuild
            <T, TTypeTo>(
            this IInjector injector) where TTypeTo : T
        {
            return InjectorExtensionUtils.BindTo<T, TTypeTo>(injector, true);
        }

        #endregion

        #region Rebind

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IBindingSyntax Rebind(this IInjector injector, Type type, object key,
                                            IDictionary<string, object> specialParameters = null,
                                            params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.Rebind(injector, type, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IBindingSyntax Rebind(this IInjector injector, Type type,
                                            IDictionary<string, object> specialParameters,
                                            params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.Rebind(injector, type, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IBindingSyntax Rebind(this IInjector injector, Type type, params IInjectionParameter[] parameters)
        {
            if (parameters == null || parameters.Length == 0)
                return InjectorExtensionUtils.Rebind(injector, type);
            return InjectorExtensionUtils.Rebind(injector, type, null, null,
                                                 InjectorUtilsInternal.ReadOnlyEmptyDictionary, parameters);
        }

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IBindingSyntax RebindInto(this IInjector injector, Type type, object key, MemberInfo member,
                                                ParameterInfo parameter = null,
                                                IDictionary<string, object> specialParameters = null,
                                                params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.Rebind(injector, type, member, parameter, specialParameters, parameters);
        }

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IBindingSyntax RebindInto(this IInjector injector, Type type, MemberInfo member,
                                                ParameterInfo parameter = null,
                                                IDictionary<string, object> specialParameters = null,
                                                params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.Rebind(injector, type, member, parameter, specialParameters, parameters);
        }

        //----------

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services <see cref="T"/>, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T> Rebind<T>(this IInjector injector, object key,
                                                         IDictionary<string, object> specialParameters = null,
                                                         params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.Rebind<T>(injector, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services <see cref="T"/>, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T> Rebind<T>(this IInjector injector,
                                                         IDictionary<string, object> specialParameters,
                                                         params IInjectionParameter[] parameters)
        {
            return InjectorExtensionUtils.Rebind<T>(injector, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services <see cref="T"/>, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T> Rebind<T>(this IInjector injector,
                                                         params IInjectionParameter[] parameters)
        {
            if (parameters == null || parameters.Length == 0)
                return InjectorExtensionUtils.Rebind<T>(injector);
            return InjectorExtensionUtils.Rebind<T>(injector, null, null, InjectorUtilsInternal.ReadOnlyEmptyDictionary,
                                                    parameters);
        }

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services <see cref="T"/>, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T> RebindInto<T>(this IInjector injector, object key, MemberInfo member,
                                                             ParameterInfo parameter = null,
                                                             IDictionary<string, object> specialParameters = null,
                                                             params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.Rebind<T>(injector, member, parameter, specialParameters, parameters);
        }

        /// <summary>
        /// Removes any existing bindings with specified condition for the specified services <see cref="T"/>, and declares a new one.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static IGenericBindingSyntax<T> RebindInto<T>(this IInjector injector, MemberInfo member,
                                                             ParameterInfo parameter = null,
                                                             IDictionary<string, object> specialParameters = null,
                                                             params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.Rebind<T>(injector, member, parameter, specialParameters, parameters);
        }

        #endregion

        #region Unbind

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void Unbind(this IInjectorBinder injector, Type type, object key,
                                  IDictionary<string, object> specialParameters = null,
                                  params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            InjectorExtensionUtils.Unbind(injector, type, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void Unbind(this IInjectorBinder injector, Type type,
                                  IDictionary<string, object> specialParameters, params IInjectionParameter[] parameters)
        {
            InjectorExtensionUtils.Unbind(injector, type, null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void Unbind(this IInjectorBinder injector, Type type, params IInjectionParameter[] parameters)
        {
            if (parameters == null || parameters.Length == 0)
            {
                InjectorExtensionUtils.Unbind(injector, type);
                return;
            }
            InjectorExtensionUtils.Unbind(injector, type, null, null, InjectorUtilsInternal.ReadOnlyEmptyDictionary,
                                          parameters);
        }

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void UnbindInto(this IInjectorBinder injector, Type type, object key, MemberInfo member,
                                      ParameterInfo parameter = null,
                                      IDictionary<string, object> specialParameters = null,
                                      params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            InjectorExtensionUtils.Unbind(injector, type, member, parameter, specialParameters, parameters);
        }

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="type">The specified service type.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void UnbindInto(this IInjectorBinder injector, Type type, MemberInfo member,
                                      ParameterInfo parameter = null,
                                      IDictionary<string, object> specialParameters = null,
                                      params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            InjectorExtensionUtils.Unbind(injector, type, member, parameter, specialParameters, parameters);
        }

        //------------

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void Unbind<T>(this IInjectorBinder injector, object key,
                                     IDictionary<string, object> specialParameters = null,
                                     params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            InjectorExtensionUtils.Unbind(injector, typeof(T), null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void Unbind<T>(this IInjectorBinder injector,
                                     IDictionary<string, object> specialParameters,
                                     params IInjectionParameter[] parameters)
        {
            InjectorExtensionUtils.Unbind(injector, typeof(T), null, null, specialParameters, parameters);
        }

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void Unbind<T>(this IInjectorBinder injector, params IInjectionParameter[] parameters)
        {
            if (parameters == null || parameters.Length == 0)
            {
                InjectorExtensionUtils.Unbind(injector, typeof(T));
                return;
            }
            InjectorExtensionUtils.Unbind(injector, typeof(T), null, null,
                                          InjectorUtilsInternal.ReadOnlyEmptyDictionary, parameters);
        }

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void UnbindInto<T>(this IInjectorBinder injector, object key, MemberInfo member,
                                         ParameterInfo parameter = null,
                                         IDictionary<string, object> specialParameters = null,
                                         params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            InjectorExtensionUtils.Unbind(injector, typeof(T), member, parameter, specialParameters, parameters);
        }

        /// <summary>
        /// Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorBinder"/>.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service. </param>
        /// <param name="parameters"> The specified parameters.</param>
        /// <returns>The fluent syntax.</returns>
        public static void UnbindInto<T>(this IInjectorBinder injector, MemberInfo member,
                                         ParameterInfo parameter = null,
                                         IDictionary<string, object> specialParameters = null,
                                         params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            InjectorExtensionUtils.Unbind(injector, typeof(T), member, parameter, specialParameters, parameters);
        }

        #endregion

        #region Can resolve

        /// <summary>
        /// Determines whether the specified request can be resolved.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/> </param>
        /// <param name="service">Service for resolve.</param>
        /// <param name="parameters">Parameters for service. </param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="searchInParent">If set to <c>true</c> search in parent bindings.</param>
        /// <param name="includeImplicitBindings">If set to <c>false</c> implicit bindings are ignored.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool CanResolve(this IInjectorResolver injector, Type service, object key,
                                      bool searchInParent = true, bool includeImplicitBindings = false,
                                      IDictionary<string, object> specialParameters = null,
                                      params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.CanResolve(injector, service, null, null, parameters, specialParameters,
                                                     searchInParent,
                                                     includeImplicitBindings);
        }

        /// <summary>
        /// Determines whether the specified request can be resolved.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/> </param>
        /// <param name="service">Service for resolve.</param>
        /// <param name="parameters">Parameters for service. </param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="searchInParent">If set to <c>true</c> search in parent bindings.</param>
        /// <param name="includeImplicitBindings">If set to <c>false</c> implicit bindings are ignored.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool CanResolve(this IInjectorResolver injector, Type service, bool searchInParent = true,
                                      bool includeImplicitBindings = false,
                                      IDictionary<string, object> specialParameters = null,
                                      params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.CanResolve(injector, service, null, null, parameters, specialParameters,
                                                     searchInParent,
                                                     includeImplicitBindings);
        }

        /// <summary>
        /// Determines whether the specified request can be resolved.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/> </param>
        /// <param name="service">Service for resolve.</param>
        /// <param name="parameters">Parameters for service. </param>
        /// <param name="key">The specified binding key. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="searchInParent">If set to <c>true</c> search in parent bindings.</param>
        /// <param name="includeImplicitBindings">If set to <c>false</c> implicit bindings are ignored.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool CanResolveInto(this IInjectorResolver injector, Type service, object key, MemberInfo member,
                                          ParameterInfo parameter = null,
                                          bool searchInParent = true, bool includeImplicitBindings = false,
                                          IDictionary<string, object> specialParameters = null,
                                          params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.CanResolve(injector, service, member, parameter, parameters, specialParameters,
                                                     searchInParent,
                                                     includeImplicitBindings);
        }

        /// <summary>
        /// Determines whether the specified request can be resolved.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjectorResolver"/> </param>
        /// <param name="service">Service for resolve.</param>
        /// <param name="parameters">Parameters for service. </param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for resolve current service.</param>
        /// <param name="searchInParent">If set to <c>true</c> search in parent bindings.</param>
        /// <param name="includeImplicitBindings">If set to <c>false</c> implicit bindings are ignored.</param>
        /// <returns><c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.</returns>
        public static bool CanResolveInto(this IInjectorResolver injector, Type service, MemberInfo member,
                                          ParameterInfo parameter = null, bool searchInParent = true,
                                          bool includeImplicitBindings = false,
                                          IDictionary<string, object> specialParameters = null,
                                          params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.CanResolve(injector, service, member, parameter, parameters, specialParameters,
                                                     searchInParent,
                                                     includeImplicitBindings);
        }

        #endregion

        #endregion

        #region Release object in scope

        /// <summary>
        /// Release specified service with specified condition in scope.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/> </param>
        /// <param name="service">Service for release.</param>
        /// <param name="key">The specified binding key.</param>
        /// <param name="specialParameters">Special parameters for release specified service.</param>
        /// <param name="needDispose">Try dispose object.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been release; otherwise, <c>false</c>.</returns>
        public static bool Release(this IInjector injector, Type service, object key, bool needDispose = true,
                                   IDictionary<string, object> specialParameters = null,
                                   params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.Release(injector, service, null, null, specialParameters, needDispose,
                                                  parameters);
        }

        /// <summary>
        /// Releases specified service with specified condition in scope.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/> </param>
        /// <param name="service">Service for release.</param>
        /// <param name="specialParameters">Special parameters for release specified service.</param>
        /// <param name="needDispose">Try dispose object.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been release; otherwise, <c>false</c>.</returns>
        public static bool Release(this IInjector injector, Type service, bool needDispose = true,
                                   IDictionary<string, object> specialParameters = null,
                                   params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.Release(injector, service, null, null, specialParameters, needDispose,
                                                  parameters);
        }

        /// <summary>
        /// Release specified service with specified condition in scope.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/> </param>
        /// <param name="service">Service for release.</param>
        /// <param name="key">The specified binding key.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for release specified service.</param>
        /// <param name="needDispose">Try dispose object.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been release; otherwise, <c>false</c>.</returns>
        public static bool ReleaseInto(this IInjector injector, Type service, object key,
                                       MemberInfo member, ParameterInfo parameter = null, bool needDispose = true,
                                       IDictionary<string, object> specialParameters = null,
                                       params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = new Dictionary<string, object>();
            SpecialParameterKeys.SetKeyedBindingParameter(specialParameters, key);
            return InjectorExtensionUtils.Release(injector, service, member, parameter, specialParameters, needDispose,
                                                  parameters);
        }

        /// <summary>
        /// Release specified service with specified condition in scope.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/> </param>
        /// <param name="service">Service for release.</param>
        /// <param name="member">The specified <see cref="MemberInfo"/> target that will receive the injection.</param>  
        /// <param name="parameter">The specifeid <see cref="ParameterInfo"/> that will receive the injection.</param>
        /// <param name="specialParameters">Special parameters for release specified service.</param>
        /// <param name="needDispose">Try dispose object.</param>
        /// <param name="parameters">The specified parameters. </param>
        /// <returns><c>True</c> if the specified service has been release; otherwise, <c>false</c>.</returns>
        public static bool ReleaseInto(this IInjector injector, Type service, MemberInfo member,
                                       ParameterInfo parameter = null, bool needDispose = true,
                                       IDictionary<string, object> specialParameters = null,
                                       params IInjectionParameter[] parameters)
        {
            if (specialParameters == null)
                specialParameters = InjectorUtilsInternal.ReadOnlyEmptyDictionary;
            return InjectorExtensionUtils.Release(injector, service, member, parameter, specialParameters, needDispose,
                                                  parameters);
        }

        #endregion

        #region Create child container

        /// <summary>
        /// Creates a child <see cref="IInjector"/>, by default, components are cloned from the parent.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="modules">The specified <see cref="InjectorModule"/> for new <see cref="IInjector"/></param>
        /// <returns>An instacne of child <see cref="IInjector"/>.</returns>
        public static IInjector CreateChild(this IInjector injector, params IInjectorModule[] modules)
        {
            return injector.CreateChild(injector.Settings.Clone(), new ComponentContainer(), true,
                                        InjectorUtilsInternal.EmptyComponents, modules);
        }

        /// <summary>
        /// Creates a child <see cref="IInjector"/>, by default, components are cloned from the parent.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="components">The specified <see cref="IComponent"/>(s).</param>
        /// <param name="modules">The specified <see cref="InjectorModule"/> for new <see cref="IInjector"/></param>
        /// <returns>An instacne of child <see cref="IInjector"/>.</returns>
        public static IInjector CreateChild(this IInjector injector, IList<IComponent> components,
                                            params IInjectorModule[] modules)
        {
            return injector.CreateChild(injector.Settings.Clone(), new ComponentContainer(), true, components, modules);
        }

        /// <summary>
        /// Creates a child <see cref="IInjector"/>, by default, components are cloned from the parent.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/> </param>
        /// <param name="settings">Settings for child <see cref="IInjector"/>.</param>
        /// <param name="modules">The specified <see cref="InjectorModule"/> for new <see cref="IInjector"/></param>
        /// <returns>An instacne of child <see cref="IInjector"/>.</returns>
        public static IInjector CreateChild(this IInjector injector, IInjectorSettings settings,
                                            params IInjectorModule[] modules)
        {
            return injector.CreateChild(settings, new ComponentContainer(), true, InjectorUtilsInternal.EmptyComponents,
                                        modules);
        }

        /// <summary>
        /// Creates a child <see cref="IInjector"/>, by default, components are cloned from the parent.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/> </param>
        /// <param name="settings">Settings for child <see cref="IInjector"/>.</param>
        /// <param name="componentContainer">The specified <see cref="IComponentContainer"/>. </param>
        /// <param name="modules">The specified <see cref="InjectorModule"/> for new <see cref="IInjector"/></param>
        /// <returns>An instacne of child <see cref="IInjector"/>.</returns>
        public static IInjector CreateChild(this IInjector injector, IInjectorSettings settings,
                                            IComponentContainer componentContainer, params IInjectorModule[] modules)
        {
            return injector.CreateChild(settings, componentContainer, true, InjectorUtilsInternal.EmptyComponents,
                                        modules);
        }

        /// <summary>
        /// Creates a child <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/> </param>
        /// <param name="settings">Settings for child <see cref="IInjector"/>.</param>
        /// <param name="componentContainer">The specified <see cref="IComponentContainer"/>. </param>
        /// <param name="cloneComponents">Specifies whether to clone the components from the parent.</param>
        /// <param name="modules">The specified <see cref="InjectorModule"/> for new <see cref="IInjector"/></param>
        /// <returns>An instacne of child <see cref="IInjector"/>.</returns>
        public static IInjector CreateChild(this IInjector injector, IInjectorSettings settings,
                                            IComponentContainer componentContainer, bool cloneComponents,
                                            params IInjectorModule[] modules)
        {
            return injector.CreateChild(settings, componentContainer, cloneComponents,
                                        InjectorUtilsInternal.EmptyComponents, modules);
        }

        #endregion

        #region Modules

        /// <summary>
        /// Creates a new instance of the module and loads it into the <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>  </param>
        /// <typeparam name="T">The type of the module.</typeparam>
        public static void Load<T>(this IInjector injector) where T : IInjectorModule
        {
            injector.Load(typeof(T));
        }

        /// <summary>
        /// Unloads the module with the specified <see cref="T"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>  </param>
        /// <typeparam name="T">The type of the module.</typeparam>
        public static void Unload<T>(this IInjector injector) where T : IInjectorModule
        {
            injector.Unload(typeof(T));
        }

        /// <summary>
        /// Loads the module(s) into the <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>  </param>
        /// <param name="modules">The specified modules.</param>
        public static void Load(this IInjector injector, IEnumerable<IInjectorModule> modules)
        {
            Validate.ArgumentNotNull(modules, "modules");
            foreach (var injectorModule in modules)
            {
                injector.Load(injectorModule);
            }
        }

        /// <summary>
        /// Loads modules defined in the specified assemblies.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="assemblies">The assemblies to search.</param>
        public static void LoadModules(this IInjector injector, params Assembly[] assemblies)
        {
            InjectorExtensionUtils.LoadModules(injector, assemblies);
        }

        #endregion

        #region Inject

        /// <summary>
        /// Injects properties, methods, fields in specified object.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="target">The specified object for inject.</param>
        /// <param name="parameters"> The specified <see cref="IInjectionParameter"/>.</param>
        public static void Inject<T>(this IInjector injector, ref T target, params IInjectionParameter[] parameters)
        {
            Validate.ArgumentNotNull(target, "target");
            injector.Inject(ref target, injector.CreateContext(target.GetType(), null, null, parameters,
                                                               InjectorUtilsInternal.ReadOnlyEmptyDictionary));
        }

        /// <summary>
        /// Injects properties, methods, fields in specified object.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="target">The specified object for inject.</param>
        /// <param name="parameters"> The specified <see cref="IInjectionParameter"/>.</param>
        public static void Inject<T>(this IInjector injector, T target, params IInjectionParameter[] parameters)
            where T : class
        {
            Validate.ArgumentNotNull(target, "target");
            injector.Inject(ref target, injector.CreateContext(target.GetType(), null, null, parameters,
                                                               InjectorUtilsInternal.ReadOnlyEmptyDictionary));
        }

        #endregion

        #region Decorators

        /// <summary>
        /// Decorate all components implementing service <typeparamref name="TService"/> using the provided <paramref name="decorator"/> function.
        /// </summary>
        /// <typeparam name="TService">Service type being decorated.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="decorator">Function decorating a component instance.</param>
        public static IDynamicConverter BindAsDecoratorForAll<TService>(this IInjector injector, Func<IBindingContext, TService, TService> decorator)
        {
            return InjectorExtensionUtils.BindAsDecoratorForAll(injector, decorator);
        }

        /// <summary>
        /// Decorate components with specified condition implementing service <typeparamref name="TService"/> using the provided <paramref name="decorator"/> function.
        /// </summary>
        /// <typeparam name="TService">Service type being decorated.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="buildCondition">The specified delegate to build condition.</param>
        /// <param name="decorator">Function decorating a component instance.</param>
        public static IDynamicConverter BindAsDecoratorFor<TService>(this IInjector injector, Action<IConditionBuilder<TService>> buildCondition, Func<IBindingContext, TService, TService> decorator)
        {
            return InjectorExtensionUtils.BindAsDecoratorFor(injector, buildCondition, decorator);
        }

        /// <summary>
        /// Unregisters all decorators for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        public static bool UnbindAllDecoratorsFor<TService>(this IInjector injector)
        {
            return InjectorExtensionUtils.UnbindAllDecoratorsFor<TService>(injector);
        }

        /// <summary>
        /// Unregisters decorators for the specified service, with specific condition.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="member">Type when injected specified service.</param>
        /// <param name="parameter"> </param>
        /// <param name="specialParameters"> </param>
        /// <param name="parameters">The specified binding parameters. </param>
        public static bool UnbindDecoratorsFor<TService>(this IInjector injector, MemberInfo member, ParameterInfo parameter,
                                                         IDictionary<string, object> specialParameters, IList<IInjectionParameter> parameters)
        {
            return InjectorExtensionUtils.UnbindDecoratorsFor<TService>(injector, member, parameter, specialParameters, parameters);
        }

        #endregion

        #region Adapters

        /// <summary>
        /// Adapts all components implementing service <typeparamref name="TFrom"/> to provide <typeparamref name="TTo"/> using the provided <paramref name="adapter"/> function.
        /// </summary>
        /// <typeparam name="TFrom">Service type to adapt from.</typeparam>
        /// <typeparam name="TTo">Service type to adapt to. Must not be the same as <typeparamref name="TFrom"/>.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="adapter">Function adapting <typeparamref name="TFrom"/> to service <typeparamref name="TTo"/>.</param>
        public static IDynamicConverter BindAsAdapterForAll<TFrom, TTo>(this IInjector injector, Func<IBindingContext, TFrom, TTo> adapter)
        {
            return InjectorExtensionUtils.BindAsAdapterForAll(injector, adapter);
        }

        /// <summary>
        /// Adapts components with specified condition implementing service <typeparamref name="TFrom"/> to provide <typeparamref name="TTo"/> using the provided <paramref name="adapter"/> function.
        /// </summary>
        /// <typeparam name="TFrom">Service type to adapt from.</typeparam>
        /// <typeparam name="TTo">Service type to adapt to. Must not be the same as <typeparamref name="TFrom"/>.</typeparam>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="buildCondition">The specified delegate to build condition.</param>
        /// <param name="adapter">Function adapting <typeparamref name="TFrom"/> to service <typeparamref name="TTo"/>.</param>
        public static IDynamicConverter BindAsAdapterFor<TFrom, TTo>(this IInjector injector, Action<IConditionBuilder<TTo>> buildCondition, Func<IBindingContext, TFrom, TTo> adapter)
        {
            return InjectorExtensionUtils.BindAsAdapterFor(injector, buildCondition, adapter);
        }


        /// <summary>
        /// Unregisters all adapters for the specified service.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        public static bool UnbindAllAdaptersFor<TFrom, TTo>(this IInjector injector)
        {
            return InjectorExtensionUtils.UnbindAllAdaptersFor<TFrom, TTo>(injector);
        }

        /// <summary>
        /// Unregisters adapters for the specified service, with specific condition.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/>.</param>
        /// <param name="member">Type when injected specified service.</param>
        /// <param name="parameter"> </param>
        /// <param name="specialParameters">The special parameters.</param>
        /// <param name="parameters">The specified binding parameters. </param>
        public static bool UnbindAdaptersFor<TFrom, TTo>(this IInjector injector, MemberInfo member, ParameterInfo parameter,
                                                         IDictionary<string, object> specialParameters, IList<IInjectionParameter> parameters)
        {
            return InjectorExtensionUtils.UnbindAdaptersFor<TFrom, TTo>(injector, member, parameter, specialParameters, parameters);
        }

        #endregion
    }
}